'''
迭代器是一个可以遍历数据集合的对象。可以通过Python内置的iter()函数将一个可迭代对象转换为迭代器。
在Python中，所有的集合对象，比如列表、元组、字典、字符串等都可以使用迭代器进行遍历。

生成器是一种特殊的迭代器，它可以通过yield语句来定义。生成器在迭代过程中逐个生成数据，
而不是一次性生成所有数据。这种逐个生成数据的方式可以减少内存的使用，特别是当数据集合非常大时。

'''
'''
迭代器是一个实现了迭代协议的对象，它可以在循环中逐个返回值，而不必将所有值一次性加载到内存中。迭代器具有两个主要方法：
1.__iter__() 方法：返回迭代器对象本身。
2.__next__() 方法：返回序列中的下一个元素。如果没有元素可以返回，会引发 StopIteration 异常。
迭代器通常用于处理大型数据集，使得只有在需要的时候才会从数据源加载数据。
'''

from collections.abc import Iterator, Iterable


#自定义迭代器:类中要实现 iter() 和 next() 方法
class myNum:
    def __iter__(self):  # 返回的是迭代器对象
        # 实例属性
        self.a = 1
        print(self, 'self')  # <__main__.myNum object at 0x100390c50> self
        return self  # 表示实例对象本身是自己的迭代器对象

    def __next__(self):
        # 举例：自增1，为了体现 next() 方法
        self.a += 1
        return self.a

if __name__ == "__main__":
    mydata = myNum()  # 创建对象
    print(isinstance(mydata, Iterable))   # 是否可迭代：True

    myIter = iter(mydata)  # 把可迭代对象变成迭代器
    print(myIter, 'myIter')   # <__main__.myNum object at 0x100390c50> myIter
    print(isinstance(mydata, Iterator))  # 是否是迭代器：实现上面2个方法时，才是迭代器：True，这句是自行判断，可以不要

    for i in range(1, 20):
        print(next(myIter))
'''
凡是可作用于 for 循环的对象都是 Iterable 类型；
凡是可作用于 next() 函数的对象都是 Iterator 类型；
集合数据类型如 list 、dict、str 等是 Iterable 但不是Iterator，不过可以通过 iter() 函数获得一个 Iterator 对象。
'''